package com.zhoug.zmui.input;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.zhoug.common.utils.StringUtils;
import com.zhoug.zmui.R;
import com.zhoug.zmui.ZMUITextView;
import com.zhoug.zmui.utils.ZMUIUtils;

import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.core.content.ContextCompat;

/**
 * 键值对组件
 * 支持垂直和水平布局
 * 支持单位、图标、清除输入，必填
 *
 * @Author: zhoug
 * @Date: 2024-07-08
 * @Description:
 */
public abstract class ZMUIInputView extends FrameLayout implements OnFocusChangeListener {
    protected static final String TAG = ">>>ZMUIInputView";
    protected static boolean DEBUG = false;
    /**
     * 左边
     */
    public static final int START = 1;
    /**
     * 右边
     */
    public static final int END = 2;
    /**
     * 1dp对应的px
     */
    protected int DP1;
    /**
     * 根布局
     */
    protected LinearLayout mRoot;
    /**
     * name TextView
     */
    protected ZMUITextView mInputNameTextView;
    /**
     * value 容器
     */
    protected ZMUIValueGroup mInputValueContainer;
    /**
     * 右边的单位 TextView
     */
    protected TextView mRightTextView;
    /**
     * 右边的图标 ImageView
     */
    protected ImageView mRightImageView;
    /**
     * 清除图标
     */
    protected ImageView mClearImageView;

    /**
     * name和value的排列方式
     * {@link LinearLayoutCompat#HORIZONTAL} 水平
     * {@link LinearLayoutCompat#VISIBLE} 垂直
     */
    private @LinearLayoutCompat.OrientationMode int mOrientation;
    /**
     * name和value间距
     */
    private int mValueMarginName = -1;

    /**
     * value组件高度
     */
    protected int mValueHeight;
    /**
     * value组件最小高度
     */
    protected int mValueMinHeight;
    /**
     * value组件最大高度
     */
    protected int mValueMaxHeight;
    /**
     * 输入清空按钮图标是否启用
     */
    protected boolean mClearIconEnable;
    protected boolean mHasFocus;

    /**
     * value背景
     */
    protected Drawable mValueBackground;
    /**
     * 右边的图标点击监听
     */
    protected OnRightIconClickListener mOnRightIconClickListener;
    /**
     * 自动验证必填项
     */
    private boolean autoValidateRequired=true;

    public ZMUIInputView(Context context) {
        this(context, null);
    }

    public ZMUIInputView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.zmui_style_ZMUIInputView);
    }

    public ZMUIInputView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        DP1 = ZMUIUtils.getDp1(context);
        init(context, attrs, defStyleAttr);
    }


    private void init(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        mRoot = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.zmui_input_view, this, false);
        addView(mRoot);
        mInputNameTextView = mRoot.findViewById(R.id.inputNameTextView);
        mInputValueContainer = mRoot.findViewById(R.id.inputValueContainer);
        mRightTextView = mRoot.findViewById(R.id.rightTextView);
        mRightImageView = mRoot.findViewById(R.id.rightImageView);
        mClearImageView = mRoot.findViewById(R.id.clearImageView);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ZMUIInputView, defStyleAttr, R.style.zmui_style_ZMUIInputView);

        int orientation = a.getInt(R.styleable.ZMUIInputView_android_orientation, LinearLayoutCompat.HORIZONTAL);
        boolean required = a.getBoolean(R.styleable.ZMUIInputView_zmui_required, false);
        boolean unRequiredTag = a.getBoolean(R.styleable.ZMUIInputView_zmui_unRequiredTag, true);
        int requiredTabGravity = a.getInt(R.styleable.ZMUIInputView_zmui_requiredTabGravity, END);
        boolean appendColon = a.getBoolean(R.styleable.ZMUIInputView_zmui_appendColon, false);
        int alignTextLength = a.getInt(R.styleable.ZMUIInputView_zmui_alignTextLength, 0);


        String name = a.getString(R.styleable.ZMUIInputView_zmui_name);
        float nameSize = a.getDimension(R.styleable.ZMUIInputView_zmui_nameSize, 0);
        int nameColor = a.getColor(R.styleable.ZMUIInputView_zmui_nameColor, 0);
        int nameStyle = a.getInt(R.styleable.ZMUIInputView_zmui_nameStyle, Typeface.NORMAL);
        int nameWidth = a.getLayoutDimension(R.styleable.ZMUIInputView_zmui_nameWidth, ViewGroup.LayoutParams.WRAP_CONTENT);
        float nameWeight = a.getFloat(R.styleable.ZMUIInputView_zmui_nameWeight, -1);
        int nameGravity = a.getInt(R.styleable.ZMUIInputView_zmui_nameGravity, Gravity.CENTER_VERTICAL | Gravity.START);
        int name_layoutGravity = a.getInt(R.styleable.ZMUIInputView_zmui_name_layoutGravity, Gravity.CENTER_VERTICAL);
        int nameMinHeight = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_nameMinHeight, -1);
        int nameMaxLines = a.getInt(R.styleable.ZMUIInputView_zmui_nameMaxLines, -1);

        autoValidateRequired = a.getBoolean(R.styleable.ZMUIInputView_zmui_autoValidateRequired, true);

        String unitText = a.getString(R.styleable.ZMUIInputView_zmui_unitText);
        float unitTextSize = a.getDimension(R.styleable.ZMUIInputView_zmui_unitTextSize, 0);
        int unitTextColor = a.getColor(R.styleable.ZMUIInputView_zmui_unitTextColor, 0);
        int unitTextStyle = a.getInt(R.styleable.ZMUIInputView_zmui_unitTextStyle, Typeface.NORMAL);
        int unitMarginLeft = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_unitMarginLeft, 0);
        Drawable icon = a.getDrawable(R.styleable.ZMUIInputView_zmui_icon);
        int iconTint = a.getColor(R.styleable.ZMUIInputView_zmui_iconTint, 0);
        int iconWidth = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconWidth, 0);
        int iconHeight = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconHeight, 0);
        int iconMarginLeft = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconMarginLeft, 0);
        int iconPaddingStart = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconPaddingStart, 0);
        int iconPaddingEnd = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconPaddingEnd, 0);
        int iconPaddingTop = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconPaddingTop, 0);
        int iconPaddingBottom = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_iconPaddingBottom, 0);
        int valueMarginName = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_valueMarginName, 0);
        mValueBackground = a.getDrawable(R.styleable.ZMUIInputView_zmui_valueBackground);
        mValueHeight = a.getLayoutDimension(R.styleable.ZMUIInputView_zmui_valueHeight, ViewGroup.LayoutParams.WRAP_CONTENT);
        int valueWidth = a.getLayoutDimension(R.styleable.ZMUIInputView_zmui_valueWidth, ViewGroup.LayoutParams.MATCH_PARENT);
        float valueWeight = a.getFloat(R.styleable.ZMUIInputView_zmui_valueWeight, -1);
        mValueMinHeight = a.getLayoutDimension(R.styleable.ZMUIInputView_zmui_valueMinHeight, 0);
        mValueMaxHeight = a.getLayoutDimension(R.styleable.ZMUIInputView_zmui_valueMaxHeight, 0);
        Drawable clearIcon = a.getDrawable(R.styleable.ZMUIInputView_zmui_clearIcon);
        if (clearIcon == null) {
            clearIcon = ContextCompat.getDrawable(getContext(), R.drawable.zmui_icon_clear);
        }
        int clearIconWidth = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconWidth, DP1 * 20);
        int clearIconHeight = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconHeight, DP1 * 20);
        int clearIconPaddingStart = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconPaddingStart, 0);
        int clearIconPaddingEnd = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconPaddingEnd, 0);
        int clearIconPaddingTop = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconPaddingTop, 0);
        int clearIconPaddingBottom = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconPaddingBottom, 0);
        int clearIconMarginStart = a.getDimensionPixelOffset(R.styleable.ZMUIInputView_zmui_clearIconMarginStart, 0);
        int clearIconTint = a.getColor(R.styleable.ZMUIInputView_zmui_clearIconTint, 0);
        boolean clearIconEnable = a.getBoolean(R.styleable.ZMUIInputView_zmui_clearIconEnable, false);


        a.recycle();
        setOrientation(orientation);

        //name
        setRequired(required, requiredTabGravity, unRequiredTag);
        setAlignTextLength(alignTextLength);
        setAppendColon(appendColon);
        setName(name);
        setTextSize(mInputNameTextView, nameSize);
        setTextColor(mInputNameTextView, nameColor);
        setTypeface(mInputNameTextView, nameStyle);
        setNameMinHeight(nameMinHeight);
        setNameMaxLines(nameMaxLines);
        setNameLayoutGravity(name_layoutGravity);
        setNameGravity(nameGravity);
        setNameLayoutParams(nameWidth, nameWeight);

        //unit
        setUnitText(unitText);
        setTextSize(mRightTextView, unitTextSize);
        setTextColor(mRightTextView, unitTextColor);
        setTypeface(mRightTextView, unitTextStyle);
        setUnitLayoutParams(unitMarginLeft);

        //icon
        setIcon(icon, iconTint);
        setIconLayoutParams(iconWidth, iconHeight, iconMarginLeft);
        mRightImageView.setPadding(iconPaddingStart, iconPaddingTop, iconPaddingEnd, iconPaddingBottom);
        setValueContainerLayout(valueMarginName);
        mInputValueContainer.setBackground(mValueBackground);
        mRightImageView.setOnClickListener(v -> {
            if (mOnRightIconClickListener != null) {
                mOnRightIconClickListener.onClick(this, v);
            }
        });
        mRightImageView.setClickable(false);
        //value
        setValueLayoutParams(valueWidth, mValueHeight, valueWeight);

        View valueView = createValueView(mInputValueContainer);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.weight = 1;
        mInputValueContainer.addView(valueView, 0, layoutParams);
        mInputValueContainer.setMaxHeight(mValueMaxHeight);
        mInputValueContainer.setMinimumHeight(mValueMinHeight);

        //clear ImageView
        if (clearIcon != null && clearIconTint != 0) {
            clearIcon.setColorFilter(iconTint, PorterDuff.Mode.SRC_IN);
        }
        mClearImageView.setImageDrawable(clearIcon);
        ViewGroup.LayoutParams clearIconLayoutParams = mClearImageView.getLayoutParams();
        clearIconLayoutParams.width = clearIconWidth;
        clearIconLayoutParams.height = clearIconHeight;
        if (clearIconLayoutParams instanceof MarginLayoutParams params) {
            params.setMarginStart(clearIconMarginStart);
        }
        mClearImageView.setLayoutParams(clearIconLayoutParams);
        mClearImageView.setPadding(clearIconPaddingStart, clearIconPaddingTop, clearIconPaddingEnd, clearIconPaddingBottom);
        mClearImageView.setClickable(true);
        mClearImageView.setOnClickListener(this::onClearClick);
        setClearIconEnable(clearIconEnable);
    }

    public void setClearIconEnable(boolean enable) {
        if (mClearIconEnable != enable) {
            mClearIconEnable = enable;
        }

    }


    public void setOrientation(int orientation) {
        if (mOrientation != orientation) {
            this.mOrientation = orientation;
            mRoot.setOrientation(orientation);
            setValueMarginName();
        }

    }

    public void setAutoValidateRequired(boolean autoValidateRequired) {
        this.autoValidateRequired = autoValidateRequired;
    }

    public boolean isAutoValidateRequired() {
        return autoValidateRequired;
    }
    public void setName(CharSequence name) {
        mInputNameTextView.setText1(name);
    }
    public CharSequence getName(){
        return mInputNameTextView.getText1();
    }

    public void setAppendColon(boolean appendColon){
        mInputNameTextView.setAppendColon(appendColon);
    }

    public void setAlignTextLength(int alignTextLength){
        mInputNameTextView.setAlignTextLength(alignTextLength);
    }
    protected void setRequired(boolean required, int requiredTagGravity, boolean unRequiredTag) {
        mInputNameTextView.setUnRequiredTag(unRequiredTag);
        mInputNameTextView.setRequiredTagGravity(requiredTagGravity);
        mInputNameTextView.setRequired(required);
    }

    public void setRequired(boolean required) {
        mInputNameTextView.setRequired(required);
    }

    public boolean isRequired(){
        return mInputNameTextView.isRequired();
    }

    public void setRequiredTagGravity(int requiredTagGravity) {
        mInputNameTextView.setRequiredTagGravity(requiredTagGravity);

    }


    public void setNameMinHeight(int minHeight) {
        if (minHeight != -1) {
            mInputNameTextView.setMinHeight(minHeight);
        }
    }

    public void setNameMaxLines(int lines) {
        if (lines != -1) {
            mInputNameTextView.setMaxLines(lines);
        }
    }


    public void setNameGravity(int gravity) {
        mInputNameTextView.setGravity(gravity);
    }

    public void setNameLayoutGravity(int gravity) {
        ViewGroup.LayoutParams layoutParams = mInputNameTextView.getLayoutParams();
        if (layoutParams instanceof LinearLayout.LayoutParams params) {
            params.gravity = gravity;
        }
        mInputNameTextView.setLayoutParams(layoutParams);
    }


    public void setUnitText(CharSequence unit) {
        mRightTextView.setText(unit);
        if (StringUtils.isNullOrEmpty(unit)) {
            mRightTextView.setVisibility(GONE);
        } else {
            mRightTextView.setVisibility(VISIBLE);
        }
    }

    protected void setTextSize(TextView textView, float textSize) {
        if (textSize > 0) {
            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        }
    }

    protected void setTextColor(TextView textView, int color) {
        if (color != 0) {
            textView.setTextColor(color);
        }
    }

    protected void setHintTextColor(TextView textView, int color) {
        if (color != 0) {
            textView.setHintTextColor(color);
        }
    }

    protected void setTypeface(TextView textView, int typeFace) {
        textView.setTypeface(Typeface.defaultFromStyle(typeFace));
    }


    protected void setNameLayoutParams(int nameWidth, float weight) {
        ViewGroup.LayoutParams layoutParams = mInputNameTextView.getLayoutParams();
        layoutParams.width = nameWidth;
        if (weight != -1) {
            if (layoutParams instanceof LinearLayout.LayoutParams params) {
                params.weight = weight;
            }
        }
        mInputNameTextView.setLayoutParams(layoutParams);
    }

    protected void setValueLayoutParams(int valueWidth, int valueHeight, float weight) {
        ViewGroup.LayoutParams layoutParams = mInputValueContainer.getLayoutParams();
        layoutParams.width = valueWidth;
        layoutParams.height = valueHeight;
        if (weight != -1) {
            if (layoutParams instanceof LinearLayout.LayoutParams params) {
                params.weight = weight;
            }
        }
        mInputValueContainer.setLayoutParams(layoutParams);
    }


    protected void setUnitLayoutParams(int unitMarginLeft) {
        ViewGroup.LayoutParams layoutParams = mRightTextView.getLayoutParams();
        if (layoutParams instanceof MarginLayoutParams params) {
            params.setMarginStart(unitMarginLeft);
        }
        mRightTextView.setLayoutParams(layoutParams);
    }

    protected void setIcon(Drawable icon, int iconTint) {
        if (icon == null) {
            mRightImageView.setVisibility(GONE);
        } else {
            mRightImageView.setVisibility(VISIBLE);
            if (iconTint != 0) {
                icon.setColorFilter(iconTint, PorterDuff.Mode.SRC_IN);
            }
            mRightImageView.setImageDrawable(icon);
        }
    }

    protected void setIconLayoutParams(int width, int height, int iconMarginLeft) {
        ViewGroup.LayoutParams layoutParams = mRightImageView.getLayoutParams();
        layoutParams.width = width;
        layoutParams.height = height;
        if (layoutParams instanceof MarginLayoutParams params) {
            params.setMarginStart(iconMarginLeft);
        }
        mRightImageView.setLayoutParams(layoutParams);
    }

    protected void setValueContainerLayout(int valueMarginName) {
        this.mValueMarginName = valueMarginName;
        setValueMarginName();
    }

    protected void setValueMarginName() {
        if (mValueMarginName != -1) {
            ViewGroup.LayoutParams layoutParams = mInputValueContainer.getLayoutParams();
            if (layoutParams instanceof MarginLayoutParams params) {
                if (mOrientation == LinearLayoutCompat.HORIZONTAL) {
                    params.setMargins(mValueMarginName, 0, 0, 0);
                } else {
                    params.setMargins(0, mValueMarginName, 0, 0);
                }
            }
            mInputValueContainer.setLayoutParams(layoutParams);
        }

    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        mInputValueContainer.setEnabled(enabled);

        if (mClearImageView != null && mClearIconEnable) {
            if (!enabled) {
                //隐藏清除按钮
                mClearImageView.setVisibility(GONE);
            }
        }
        if (mRightImageView != null) {
            mRightImageView.setClickable(enabled && mOnRightIconClickListener != null);
        }

//        refreshValueBackground();
    }

    public void setError(boolean error) {
//            refreshValueBackground();
        mInputValueContainer.setError(error);
    }

    public boolean isError() {
        return mInputValueContainer.isError();
    }

    public void setHighlight(boolean highlight) {
        mInputValueContainer.setHighlight(highlight);
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        mHasFocus=hasFocus;
        setHighlight(hasFocus);
        //改变背景
//        refreshValueBackground();
    }

//    protected void refreshValueBackground() {
//        if (mInputValueContainer != null) {
//            LogUtils.d(TAG, this+"hasFocus:" + mHasFocus);
//            if (!isEnabled()) {
//                //禁用
//                mInputValueContainer.setBackground(mValueBackground);
//                if(mValueBackground!=null){
//                    mValueBackground.setState(new int[]{-android.R.attr.state_enabled});
//                }
//            } else if (mIsError) {
//                //错误提示
//                mInputValueContainer.setBackground(mErrorBackground);
//            } else {
//                mInputValueContainer.setBackground(mValueBackground);
//                if(mValueBackground!=null){
//                    if (mHasFocus) {
//                        //聚焦
//                        mValueBackground.setState(new int[]{android.R.attr.state_focused});
//                    } else {
//                        mValueBackground.setState(new int[]{android.R.attr.state_enabled});
//                    }
//                }
//
//            }
//            mInputValueContainer.refreshDrawableState();
//        }
//    }

    public void setOnRightIconClickListener(OnRightIconClickListener onRightIconClickListener) {
        this.mOnRightIconClickListener = onRightIconClickListener;
        mRightImageView.setClickable(null != this.mOnRightIconClickListener);
    }


    /**
     * 创建值布局
     *
     * @param parent
     * @return
     */
    protected abstract View createValueView(ViewGroup parent);

    /**
     * 单击清除按钮回调
     *
     * @param view 清除按钮 {@link  #mClearImageView}
     */
    protected abstract void onClearClick(View view);


    public interface OnRightIconClickListener {
        void onClick(ZMUIInputView inputView, View icon);
    }

}
